我們可以編寫一個含有通用元素的基底模板,而不要直接在每個頁面中重複寫入這些通用元素
我們會建立一個base.html並存在跟index.html同一個資料夾內,這個檔案會有所有頁面都需要的通用元素,其他模板也都繼承自base.html,如下
<p>
<a href="{% url 'learning_logs:index' %}">Learning Log</a>
</p>
{% block content %}{% endblock %}
上面程式碼第二行{% url 'learning_logs:index' %}會生成一個URL,此URL與learning_logs/urls.py中定義名為index的URL模式比對符合,在第五行插入一對block標記,此區塊名稱叫content,是個佔位用的符號,含有的資訊會椅子模板定義
現在我們需要重新編寫index.html檔讓他繼承自base.html,如下
{% extends "learning_logs/base.html" %}
{% block content %}
<p>hello,this is weiting's learning_log</p>
{% endblock content %}
上面程式碼第一行是在說子模板第一行要有{% extends %}標記,讓Django知道是繼承哪個父模板,第三行插入{% block %}標記來定義content區塊,是將我們在learning log的文字段落插入至content
首先要來修改learning_logs資料夾裡的urls.py檔,如下
from django.conf.urls import url
from django.urls import path
from . import views
app_name='learning_logs'
urlpatterns=[
path('',views.index,name='index'),
# 顯示所有主題
path('topics/',views.topics,name='topics'),
# 顯示個別主題
path('<int:topic_id>/',views.topic,name='topic'),
]
上面程式碼第九行我們在正規表示式中加了topic/字樣,當Django在檢測請求URL時,符合比對的URL請求會被傳到views.py中的topic函式處理
上面程式碼第十二行和第九行不同的地方是多了topic_id,當使用者要看MIIA主題(id 為 1)的詳細內容介面,Django會呼叫topic視圖函式,把存放在topic_id中的值當成引數傳給它,然後依照topic_id的值來取得對應的值
from django.shortcuts import render
from .models import Topic # 匯入Topic模型
def index(request):
return render(request, 'learning_logs/index.html')
# 顯示所有主題
def topics(request):
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
# 顯示個別主題和它的entries
def topic(request, topic_id):
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context)
上面程式碼第九行topic()函式需要一個參數,Django從伺服器收到的request物件,第十行是查詢資料庫請求Topic物件,並按照date_added屬性對它們排序,第十一行是定義一個模板傳送到context字典,第十二行是除了request物件和模板路徑之外,還要把context變數給render()
顯示個別主題是從第十五行開始,第十五行除了request物建之外還需要參數的是圖函式,此函式取得topic_id的值再存到topic_id中,第十六行是用get()函式用id來取得指定主題
顯示所有主題頁面的模板會收到context字典,所以能使用topic()所提供的資料,我們要建立一個topics.html檔,一樣存在跟index.html同一個資料夾中,topics.html程式碼如下
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li>
<a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}
上面程式碼就像index.html模板一樣,會先用{%extends%}繼承base.html,再定義content區塊,第八行的for topic in topics就是遍訪context字典中的topics串列,每個for迴圈都要有像第十四行的{%endfor%},我們主題清單都會有一個連結,第十行的連結就是連結顯示對應特定主題的內容
Topics連結點進去的畫面如下
{% extends 'learning_logs/base.html' %}
{% block content %}
<p>Topic: {{ topic }}</p>
<p>Entries:</p>
<ul>
{% for entry in entries %}
<li>
<p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
<p>{{ entry.text|linebreaks }}</p>
</li>
{% empty %}
<li>
There are no entries for this topic yet.
</li>
{% endfor %}
</ul>
{% endblock content %}
上面程式碼是我們要再創一個topic.html模板,也是以base.html為基底擴充,第五行是創一個Topic變數來存放context字典,隨後我們定義了顯示項目的清單,第十一行會顯示日期時間,第十二行是確保格式有換行符號的長紀錄項目,且能讓瀏覽器解讀,以免顯示出沒有斷行超出畫面的文字區塊
點按MIIA主題時可看到其內容的畫面如下
附上排版較精美的
HackMD網址:https://hackmd.io/2M04zx0LQDuMSNXhd10Erg?both
資料來源:<<python程式設計的樂趣>>-Eric Matthes著/H&C譯
資料來源:https://blog.csdn.net/qq_28709643/article/details/79826737
資料來源:https://stackoverflow.com/questions/47661536/django-2-0-path-error-2-0-w001-has-a-route-that-contains-p-begins-wit?noredirect=1&lq=1
資料來源:https://tw.saowen.com/a/f0f2e43b86c65053ecd39c6a4c8171b09c98c65f6ded12f6d89c541190a5de02